/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.mes.service.impl;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.xy.biz.base.client.BizCodeClient;
import com.xy.biz.base.domain.req.GetBizCodeRequest;
import com.xy.biz.mes.domain.bo.*;
import com.xy.biz.mes.domain.enums.ManufactureGoodsTypeEnum;
import com.xy.biz.mes.domain.enums.ManufactureOrderStatusEnum;
import com.xy.biz.mes.domain.enums.ManufactureTaskStatusEnum;
import com.xy.biz.mes.domain.query.ManufactureOrderQuery;
import com.xy.biz.mes.domain.query.ManufactureResultQuery;
import com.xy.biz.mes.domain.query.ManufactureTaskGoodsQuery;
import com.xy.biz.mes.domain.query.ManufactureTaskQuery;
import com.xy.biz.mes.domain.req.HandOverGoodsRequest;
import com.xy.biz.mes.manager.ManufactureOrderManager;
import com.xy.biz.mes.manager.ManufactureResultManager;
import com.xy.biz.mes.manager.ManufactureTaskManager;
import com.xy.biz.mes.service.ManufactureResultService;
import com.xy.lang.enums.HandOverResultEnum;
import com.xy.lang.util.ResultUtils;
import com.xy.tool.context.UserContextHolder;
import com.xy.tool.gid.service.GidService;
import com.xy.tool.util.BeanUtilsEx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xy.lang.domain.Result;
import org.springframework.util.CollectionUtils;

/**
 *
 *
 * @author zgy
 * @date 2022-2-11
 */
@Service
public class ManufactureResultServiceImpl implements ManufactureResultService {

    @Autowired
    private GidService gidService;
    @Autowired
    private BizCodeClient bizCodeClient;
    @Autowired
    private ManufactureResultManager manufactureResultManager;
    @Autowired
    private ManufactureOrderManager manufactureOrderManager;
    @Autowired
    private ManufactureTaskManager manufactureTaskManager;

//    @Override
//    public Result<?> saveManufactureResult(ManufactureResultBO manufactureResultBO) {
//        List<HandOverGoodsRequest> handOverGoodsList = manufactureResultBO.getHandOverGoodsList();
//        if (CollectionUtils.isEmpty(handOverGoodsList)) {
//            return Result.ofBadRequest();
//        }
//        Map<Long, Integer> manufactureTaskGoodsIdMap = handOverGoodsList.stream()
//                .collect(Collectors.toMap(HandOverGoodsRequest::getManufactureTaskGoodsId, HandOverGoodsRequest::getHandOverResult, (e1, e2) -> e2));
//        List<ManufactureTaskGoodsBO> manufactureTaskGoodsBOList = manufactureTaskManager.listManufactureTaskGoods(ManufactureTaskGoodsQuery.max()
//                .manufactureTaskGoodsIdList(new ArrayList<>(manufactureTaskGoodsIdMap.keySet()))
//                .type(ManufactureGoodsTypeEnum.PRODUCTION.getCode())
//                .handOverResult(HandOverResultEnum.UNDO.getCode())
//                .checkFlag(true)
//                .build());
//        if (CollectionUtils.isEmpty(manufactureTaskGoodsBOList)) {
//            return Result.ofErrorData("未查询到相关明细！");
//        }
//        Set<Long> manufactureTaskIdSet = manufactureTaskGoodsBOList.stream()
//                .map(ManufactureTaskGoodsBO::getManufactureTaskId)
//                .collect(Collectors.toSet());
//        if (CollectionUtils.isEmpty(manufactureTaskIdSet)) {
//            return Result.ofBadRequest();
//        }
//        List<ManufactureTaskBO> manufactureTaskBOList =
//                manufactureTaskManager.listManufactureTask(ManufactureTaskQuery.max()
//                        .manufactureTaskIdList(new ArrayList<>(manufactureTaskIdSet))
//                        .status(ManufactureTaskStatusEnum.REVIEWED.getCode())
//                        .build());
//        if (CollectionUtils.isEmpty(manufactureTaskBOList)) {
//            return Result.ofNotFound("未查询到已复核的任务");
//        }
//        if (!Objects.equals(manufactureTaskBOList.size(), manufactureTaskIdSet.size())) {
//            manufactureTaskIdSet.removeAll(manufactureTaskBOList.stream().map(ManufactureTaskBO::getManufactureTaskId).collect(Collectors.toSet()));
//            return Result.ofNotFound("存在未复核的任务" + manufactureTaskIdSet);
//        }
////
////        List<ManufactureResultGoodsBO> exisitingManufactureResultGoodsBOList =
////                manufactureResultManager.listManufactureResultGoods(ManufactureResultQuery.max()
////                        .manufactureTaskIdList(new ArrayList<>(manufactureTaskIdSet)).build());
////        if (!CollectionUtils.isEmpty(exisitingManufactureResultGoodsBOList)) {
////            return Result.ofBadRequest("存在已交付的任务：" +
////                    exisitingManufactureResultGoodsBOList.stream()
////                            .map(ManufactureResultGoodsBO::getManufactureTaskCode)
////                            .collect(Collectors.toSet()));
////        }
//
//        Set<Long> manufactureOrderIdSet =
//                manufactureTaskBOList.stream().map(ManufactureTaskBO::getManufactureOrderId).collect(Collectors.toSet());
//        List<ManufactureOrderBO> manufactureOrderBOList = manufactureOrderManager.listManufactureOrder(ManufactureOrderQuery.max()
//                .manufactureOrderIdList(new ArrayList<>(manufactureOrderIdSet))
//                //.status(ManufactureOrderStatusEnum.FINISHED.getCode())
//                .build());
//
//        if (CollectionUtils.isEmpty(manufactureOrderBOList)) {
//            return Result.ofNotFound("未查询到相关通知单：" + manufactureOrderIdSet);
//        }
//        if (manufactureOrderIdSet.size() != manufactureOrderBOList.size()) {
//            manufactureOrderIdSet.removeAll(manufactureOrderBOList.stream()
//                    .map(ManufactureOrderBO::getManufactureOrderId).collect(Collectors.toSet()));
//            return Result.fail("未查询到相关通知单：" + manufactureOrderIdSet);
//        }
//        //List<ManufactureTaskGoodsBO> mergedManufactureTaskGoodsList = merge(manufactureTaskGoodsBOList);
//        List<ManufactureResultGoodsBO> manufactureResultGoodsBOList = new ArrayList<>();
//        manufactureTaskGoodsBOList.forEach(e -> {
//            e.setHandOverResult(manufactureTaskGoodsIdMap.get(e.getManufactureTaskGoodsId()));
//            e.setFromStatusSet(Stream.of(HandOverResultEnum.UNDO.getCode()).collect(Collectors.toSet()));
//            ManufactureResultGoodsBO manufactureResultGoodsBO = BeanUtilsEx.copyProperties(e, ManufactureResultGoodsBO::new);
//            manufactureResultGoodsBO.setHandOverResult(manufactureTaskGoodsIdMap.get(e.getManufactureTaskGoodsId()));
//            manufactureResultGoodsBO.setManufactureTaskGoodsBO(e);
//            manufactureResultGoodsBOList.add(manufactureResultGoodsBO);
//        });
//        List<ManufactureResultBO> manufactureResultBOList = group(manufactureResultBO, manufactureResultGoodsBOList);
//        build(manufactureResultBOList);
//        int affectedRows = manufactureResultManager.saveAllManufactureResult(manufactureResultBOList);
//        if (affectedRows > 0) {
//            return Result.success();
//        }
//        return Result.ofErrorRowsAffected();
//    }

    /**
     * 同通知单下相同的货品进行合并
     */
    private List<ManufactureTaskGoodsBO> merge(List<ManufactureTaskGoodsBO> manufactureTaskGoodsBOList) {
        manufactureTaskGoodsBOList.forEach(e -> {
            ManufactureTaskGoodsBO.GoodsWrapper goodsWrapper = BeanUtilsEx.copyProperties(e, ManufactureTaskGoodsBO.GoodsWrapper::new);
            e.setGoodsInfo(goodsWrapper);
        });
        Map<ManufactureTaskGoodsBO.GoodsWrapper, ManufactureTaskGoodsBO> taskGoodsBOMap =
                manufactureTaskGoodsBOList.stream()
                        .collect(Collectors.toMap(ManufactureTaskGoodsBO::getGoodsInfo, e -> e, (e1, e2) -> {
                            e2.setFactCount((e1.getFactCount() + e2.getFactCount()));
                            e2.setFactQuantity((e1.getFactQuantity() + e2.getFactQuantity()));
                            return e2;
                        }));
        return new ArrayList<>(taskGoodsBOMap.values());
    }

//    private List<ManufactureResultBO> group(ManufactureResultBO manufactureResultBO, List<ManufactureResultGoodsBO> manufactureResultGoodsBOList) {
//        Map<Integer, List<ManufactureResultGoodsBO>> groupByHandOverResult =
//                manufactureResultGoodsBOList.stream().collect(Collectors.groupingBy(ManufactureResultGoodsBO::getHandOverResult));
//        List<ManufactureResultBO> manufactureResultBOList = new ArrayList<>();
//        groupByHandOverResult.forEach((k, v) -> {
//            ManufactureResultBO manufactureResult = new ManufactureResultBO();
//            manufactureResult.setMemo(manufactureResultBO.getMemo());
//            manufactureResult.setHandOverResult(k);
//            manufactureResult.setManufactureResultGoodsList(groupByHandOverResult.get(k));
//            manufactureResultBOList.add(manufactureResult);
//        });
//        return manufactureResultBOList;
//    }
//
//    private void build(Collection<ManufactureResultBO> collection) {
//        collection.forEach(manufactureResultBO -> {
//            GetBizCodeRequest getBizCodeRequest = GetBizCodeRequest.builder().code("MT").build();
//            manufactureResultBO.setManufactureResultId(gidService.generate());
//            manufactureResultBO.setManufactureResultCode(ResultUtils.get(bizCodeClient.nextBizCode(getBizCodeRequest)));
//            manufactureResultBO.setCreateTime(LocalDateTime.now());
//            manufactureResultBO.setStatus(0);
//            manufactureResultBO.setCreateUserId(UserContextHolder.getUserId());
//            manufactureResultBO.setCreateUserName(UserContextHolder.getUserName());
//            manufactureResultBO.setTenantId(UserContextHolder.getTenantId());
//            manufactureResultBO.setUpdateTime(LocalDateTime.now());
//            manufactureResultBO.getManufactureResultGoodsList().forEach(e -> {
//                e.setManufactureResultGoodsId(gidService.generate());
//                e.setManufactureResultId(manufactureResultBO.getManufactureResultId());
//                e.setManufactureResultCode(manufactureResultBO.getManufactureResultCode());
//            });
//        });
//    }

    @Override
    public Result<?> updateManufactureResult(ManufactureResultBO manufactureResultBO) {
        int affectedRows = manufactureResultManager.updateManufactureResult(manufactureResultBO);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public Result<?> deleteManufactureResult(java.lang.Long manufactureResultId) {
        int affectedRows = manufactureResultManager.deleteManufactureResult(manufactureResultId);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public ManufactureResultBO getManufactureResult(java.lang.Long manufactureResultId) {
        return manufactureResultManager.getManufactureResult(manufactureResultId);
    }

    @Override
    public List<ManufactureResultBO> listManufactureResultById(Collection<java.lang.Long> collection) {
        return manufactureResultManager.listManufactureResultById(collection);
    }

    @Override
    public List<ManufactureResultBO> listManufactureResult(ManufactureResultQuery query) {
        return manufactureResultManager.listManufactureResult(query);
    }

    @Override
    public int countManufactureResult(ManufactureResultQuery query) {
        return manufactureResultManager.countManufactureResult(query);
    }

}
